﻿using LightSO.ILibrary;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace LightSO.Extensions
{
    public static class ConvertionExtension
    {
        /// <summary>
        /// 尝试将对象转换为指定的类型
        /// </summary>
        /// <typeparam name="T">要转换的目标类型</typeparam>
        /// <param name="value">要转换的对象</param>
        /// <returns>转换后的结果,转换不成功返回类型默认值</returns>
        public static T Parse<T>(this string value)
        {
            return SpringExtension.Ioc<ISerializerHelper>().Parse<T>(value);
        }

        public static string ToJson(this object obj)
        {
            return SpringExtension.Ioc<ISerializerHelper>().ToJson(obj);
        }

        public static Stream ToStream<T>(this T obj)
        {
            return obj.ToJson().ToStream();
        }

        public static Stream ToStream(this string text)
        {
            return SpringExtension.Ioc<ISerializerHelper>().ToStream(text);
        }

        public static T ToInstance<T>(this Stream stream)
        {
            // convert stream to string  
            stream.Position = 0;
            StreamReader reader = new StreamReader(stream);
            string text = reader.ReadToEnd();

            return text.Parse<T>();
        }

        public static T FromJson<T>(string json)
        {
            return SpringExtension.Ioc<ISerializerHelper>().FromJson<T>(json);
        }

        /// <summary>
        /// 对象间的转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T2 ConvertTo<T1, T2>(this T1 value) 
        {
            return SpringExtension.Ioc<ISerializerHelper>().ConvertTo<T1, T2>(value);
        }


        /// <summary>
        /// XML序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static XDocument ToXDoc<T>(T obj)
        {
            return SpringExtension.Ioc<ISerializerHelper>().ToXDoc<T>(obj);
        }

        /// <summary>
        /// XML反序列化
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="document">Xml文档</param>
        /// <returns></returns>
        public static T FromXDoc<T>(this XDocument document)
        {
            return SpringExtension.Ioc<ISerializerHelper>().FromXDoc<T>(document);
        }


        /// <summary>
        /// XML反序列化
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="xml">Xml字符串</param>
        /// <returns></returns>
        public static T FromXml<T>(string xml)
        {
            return SpringExtension.Ioc<ISerializerHelper>().FromXml<T>(xml);
        }

        /// <summary>
        /// XML反序列化
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="xmlPath">xml文件路径(物理路径)</param>
        /// <returns></returns>
        public static T FromXmlFile<T>(string xmlPath)
        {
            return SpringExtension.Ioc<ISerializerHelper>().FromXmlFile<T>(xmlPath);
        }

        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <returns>原始值，当原始值不为 null 或 DBbNull，否则使用代换的默认值</returns>
        public static T IfNull<T>(this T value, T defaultValue)
        {
            return SpringExtension.Ioc<ISerializerHelper>().IfNull(value, defaultValue);
        }

        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <returns>当原始值不为 null 或 DBbNull，返回原始值，否则返回代换的默认值</returns>
        public static object IfNull(this object value, object defaultValue)
        {
            return SpringExtension.Ioc<ISerializerHelper>().IfNull(value, defaultValue);
        }


        /// <summary>
        /// 若值是 null 则使用指定值代换
        /// </summary>
        /// <typeparam name="TInput">值类型</typeparam>
        /// <typeparam name="TOut">输出值类型</typeparam>
        /// <param name="value">原始值</param>
        /// <param name="defaultValue">当值为 null 时用于代换的默认值</param>
        /// <param name="converter">当值不为空时，对值进行类型转换的转换器。</param>
        /// <returns>当原始值不为 null 或 DBbNull，返回转换后的原始值，否则返回代换的默认值</returns>
        public static TOut IfNull<TInput, TOut>(this TInput value, TOut defaultValue, Func<TInput, TOut> converter)
        {
            return SpringExtension.Ioc<ISerializerHelper>().IfNull(value, defaultValue, converter);
        }



        /// <summary>
        /// 将对象所有属性转换为对象字典
        /// </summary>
        /// <param name="obj">要转换为对象字典的对象</param>
        /// <returns>对象图</returns>
        public static IDictionary<string, string> ToDictionary(this object obj)
        {
            return SpringExtension.Ioc<ISerializerHelper>().ToDictionary(obj);
        }
    }
}
